Skip to main content

Setting up Garage Integration

Out of the Box

Integration with your garage resource is entirely OPTIONAL, by default r14-evidence is set up to integrate with qb-garages or esx_garage to automatically load evidence when vehicles are removed from a garage or to unload evidence from the main server table when a vehicle is placed into one. This is NOT required, but makes our vehicle evidence handling on the server side a little more resource efficient as it can detect when it needs to load vehicle evidence and when it can drop it from the server table. If you have a custom garage script, the script will load evidence automatically when it is created while in the vehicle, and it will simply remain in the server-side table.

r14-evidence Gararge Config Table
Config.VehInAndOut = { -- this OPTIONALLY configures your server side event that triggers when garaging or ungaraging a vehicle, the paramaters for base qb-garages are included, cd_garages is not supported
InEvent = Config.Framework.ESX and 'esx_garage:updateOwnedVehicle' or 'qb-garage:server:updateVehicle',
InState = Config.Framework.ESX and true or 1, -- the state receieved when placing a vehicle in a garage
InStateVar = 1, -- the argument that is received for the vehicle state when putting it in a garage
InStateVarSubfield = nil, -- the subfield of the in state var in the table that is supplied, you can use a period to search multiple subfields
InPlateVar = Config.Framework.ESX and 4 or 5, -- the argument that is received for the vehicle plate when putting it in a garage
InPlateVarSubfield = Config.Framework.ESX and 'vehicleProps.plate', -- use a . to access further subfields
OutEvent = Config.Framework.ESX and 'esx_garage:updateOwnedVehicle' or 'qb-garage:server:updateVehicleState',
OutState = Config.Framework.ESX and false or 0,
OutStateVar = 1,
OutStateVarSubfield = nil, -- the subfield of the out state var in the table that is supplied, you can use a period to search multiple subfields
OutPlateVar = Config.Framework.ESX and 4 or 2,
OutPlateVarSubfield = Config.Framework.ESX and 'vehicleProps.plate', -- use a . to access further subfields
}
caution

Never make changes to ANY script without making a backup first, you never know what might happen!

Integrating A Third Party Script

If you desire to configure r14-evidence to integreate with your garage script, you can use the following guide to help you do so, but it is important to note that the script does not require it to function properly! By default, any existing evidence in the vehicle database will be loaded when a player either generates evidence in that vehicle, or when they search that vehicle for evidence. It will simply remain in the server evidence table until the script restarts, but will not cause issues with the script beyond taking up additional memory.

To better understand on how this config works, lets take a look at an older version of a popular modification of qb-garages by JDev, which uses a network event triggers of the same name, but with differently ordered arguments.

tip

This script was recently modified as of 10/2022 and no longer requires a modification to the config to be compatible!

JonasDev99/qb-garages Server-side Network Event Handler

RegisterNetEvent('qb-garage:server:updateVehicle', function(state, fuel, engine, body, properties, plate, garage, location, damage)
if location and type(location) == 'vector3' then
if StoreDamageAccuratly then
MySQL.update('UPDATE player_vehicles SET state = ?, garage = ?, fuel = ?, engine = ?, body = ?, mods = ?, parkingspot = ?, damage = ? WHERE plate = ?',{state, garage, fuel, engine, body, json.encode(properties), json.encode(location), json.encode(damage), plate})
else
MySQL.update('UPDATE player_vehicles SET state = ?, garage = ?, fuel = ?, engine = ?, body = ?, mods = ?, parkingspot = ? WHERE plate = ?',{state, garage, fuel, engine, body, json.encode(properties), json.encode(location), plate})
end
else
if StoreDamageAccuratly then
MySQL.update('UPDATE player_vehicles SET state = ?, garage = ?, fuel = ?, engine = ?, body = ?, mods = ?, damage = ? WHERE plate = ?',{state, garage, fuel, engine, body, json.encode(properties), json.encode(damage), plate})
else
MySQL.update('UPDATE player_vehicles SET state = ?, garage = ?, fuel = ?, engine = ?, body = ?, mods = ? WHERE plate = ?', {state, garage, fuel, engine, body, json.encode(properties), plate})
end
end
end)

Here in 'qb-garage:server:updateVehicle' we can see that our original config uses this event to track when a vehicle is returned to it's garage, it will check the argument at the 1 position according to InStateVar, and if it equals the value defined in InState r14-evidence will then save the vehicle's evidence to database and remove it from it's main evidence table. To do this, it needs to find the plate of the vehicle in question, and checks the argument in position 5 as defined in InPlateVar. When it does this however, it pulls the vehicle properties table. In this case, we would need to change InPlateVar to 6 in order it to properly access the plate of this function!

JonasDev99/qb-garages Server-side Network Event Handler
RegisterNetEvent('qb-garage:server:updateVehicleState', function(state, plate, garage)
MySQL.update('UPDATE player_vehicles SET state = ?, garage = ?, depotprice = ? WHERE plate = ?',{state, garage, 0, plate})
end)

To properly determine when a vehicle is pulled out of a garage, and to load it's evidence straight away, we again go to the server/main.lua to find and access the 'qb-garage:server:updateVehicleState'network event. Here, we check the OutStateVar at position 1 and compare it to the OutState. When it matches this, we then pull the plate from argument 2 as defined in OutPlateVar and r14-evidence subsequently loads the vehicle evidence from the database.

Events With Arguments That Are Tables

If you are using a garage script which sends information using arguments which are a table containing the necessary information to either store/spawn the vehicle and it's properties, you can use the subfield variables in the config to accurately access them. Lets go ahead and create a custom version of the above event that uses a table to send all the information, and then create a configuration for it.

Custom Version of JonasDev99/qb-garages Server-side Network Event Handler
RegisterNetEvent('qb-garage:server:updateVehicleState', function(data)
MySQL.update('UPDATE player_vehicles SET state = ?, garage = ?, depotprice = ? WHERE plate = ?',{data.state, data.info.garage, 0, data.info.plate})
end)

Here we see instead of getting multiple arguments containing our information, we simply get one argument named data which supplies the necessary information for our event handler. Now we must modify our config table for garages to correctly access this table! First lets go ahead and attempt to figure out the structure of the table. Above we can see that not only do we have the data table, but two values stored in a table contained within the data.info subfield. We can use the json.enocode(data, {indent = true}) function to convert this table to a string to reveal more about how it is structured.

Data Argument Structure
data = {
state = 3, -- this is usually 0 in this and most scripts, but we will set it to 3 to demonstrate in the config how to match it
info = {
garage = 'pillbox',
plate = 'MAD OOC'
properties = {
color = 117,
fuel = 99,
}
}
}

We can see that we get the state of the vehicle (whether it is in a garage or not), as long as additional information about the vehicle that is being used by the script to store in the database. Not all of this information is needed to integrate with r14-evidence, we simply need to find the plate being used which we can see in the data.info.plate table above. To access this subfield we will need to create the string info.plate in OutPlateVarSubfield to access both the info subfield and then the plate value contained in it. Our config table will now look like this:

r14-evidence Gararge Config Table
Config.VehInAndOut = { -- this OPTIONALLY configures your server side event that triggers when garaging or ungaraging a vehicle, the paramaters for base qb-garages are included, cd_garages is not supported
InEvent = Config.Framework.ESX and 'esx_garage:updateOwnedVehicle' or 'qb-garage:server:updateVehicle',
InState = Config.Framework.ESX and true or 1, -- the state receieved when placing a vehicle in a garage
InStateVar = 1, -- the argument that is received for the vehicle state when putting it in a garage
InStateVarSubfield = nil, -- the subfield of the in state var in the table that is supplied, you can use a period to search multiple subfields
InPlateVar = Config.Framework.ESX and 4 or 5, -- the argument that is received for the vehicle plate when putting it in a garage
InPlateVarSubfield = Config.Framework.ESX and 'vehicleProps.plate', -- use a . to access further subfields
OutEvent = 'qb-garage:server:updateVehicleState',
OutState = 3, -- we match the 3 received in state
OutStateVar = 1, --
OutStateVarSubfield = 'state',
OutPlateVar = 1,
OutPlateVarSubfield ='info.plate', -- use a . to access further subfields
}

We set the OutEvent equal to the event being triggered which is 'qb-garage:server:updateVehicleState', becuase we recieve a state value of 3 in our table, we will want to set OutState equal to 3 so that it does not trigger when a vehicle is being put away. We are receiving the data table as the first argument, so OutStateVar remains 1, and this is also where we receive our plate so we will set OutPlateVar equal to 1 as well. Finally, we need to access our plate at data.info.plate so we set the OutPlateVarSubfield equal ot 'info.plate'.